module Text.ParserCombinators.Table.CellParser 
       (SParser
       , liftParser
       , mayBe
       , skip
       , double
       , idouble
       , int
       , string ) where


import Text.ParserCombinators.Table.TypeParser
import Text.ParserCombinators.Parsec.Prim
import Text.ParserCombinators.Parsec.Combinator
import qualified Text.ParserCombinators.Parsec.Char as C

type SParser = GenParser String ()

liftParser :: Parser a -> SParser a
liftParser p = try $ do
  s <- string
  case parse p "" s of
    Left e  -> fail $ show e
    Right x -> return x

-- | @string@ parses one string

string :: SParser String
string = anyToken

-- | @skip@ parses some string from list and skeep it

skip :: SParser ()
skip = string >> return ()

mayBe :: (Num a) => SParser a -> SParser (Maybe a)
mayBe p = (Just `fmap` p) <|> liftParser undef where
  undef = do 
    C.string "undef"
    return Nothing

-- | @double@ parses a double value in the following formats: 
-- 3.14 .14 3. 314E-2 314e-2 .314E1 .314e1 .314d1 .314D1 0.314e1

double :: SParser Double
double = liftParser $ do
  f <- floatParser
  eof
  return f

-- | @int@ parses an integer value look like 1024, -1024 

int :: SParser Int
int = liftParser $ do
  i <- integerParser
  eof
  return i
      
-- | @idouble@ parses a double value even it like integer

idouble :: SParser Double
idouble = double <|> (fromIntegral `fmap` int)
